package ru.dc.gui.swing;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jdesktop.swingx.JXTable;
import ru.dc.Application;
import ru.dc.ConnectionManager;
import ru.dc.gui.swing.util.*;
import ru.dc.object.*;
import ru.dc.object.commands.Search;
import ru.dc.object.events.hub.HubEvent;
import ru.dc.object.events.hub.SearchResultRecieved;

import javax.swing.*;
import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;
import javax.swing.table.TableColumn;
import java.awt.*;
import java.awt.event.*;

/**
 * Created by IntelliJ IDEA.
 * User: deady
 * Date: 12.10.2010
 * Time: 22:37:06
 */
public class SearchWindow extends Tab {
    private JTextField searchPattern;
    private JXTable resultsTable;
    private JButton searchBtn;
    private JPanel rootPanel;
    private JXTable hubFilter;
    private JScrollPane hubFilterScrollPane;
    private JComboBox fileType;
    private JComboBox sizeType;
    private JTextField size;
    private JComboBox searchMult;
    private JLabel foundLabel;
    private JButton clearBtn;
    private HubEventListener listener;
    private Log logger = LogFactory.getLog(getClass());
    private ServerInfoRenderer serverInfoRenderer;
    private boolean active = false;


    public void init() {

        setIcon(IconLoader.getInstance().getIcon("search-icon.png"));

        //настраиваем таблицу - фильтры по хабам
        final HubFilterTableModel hubFilterTableModel = new HubFilterTableModel();
        hubFilter.setModel(hubFilterTableModel);
        for (ServerInfo info : Application.getApplication().getConnectionManager().enumerateHubConnections()) {
            hubFilterTableModel.addHub(info);
        }
        serverInfoRenderer = new ServerInfoRenderer();
        hubFilter.setDefaultRenderer(ServerInfo.class, serverInfoRenderer);

        //слушатель фильтрует записи в таблице результатов по выбранным хабам в фильтре хабов
        hubFilterTableModel.addTableModelListener(new TableModelListener() {

            public void tableChanged(TableModelEvent e) {

                final java.util.List<ServerInfo> selected = hubFilterTableModel.getSelected();

                resultsTable.setRowFilter(new RowFilter<Object, Object>() {
                    @Override
                    public boolean include(Entry<? extends Object, ? extends Object> entry) {
                        SearchResultsTableModel model = (SearchResultsTableModel) entry.getModel();
                        final ServerInfo serverInfo = model.getResult((Integer) entry.getIdentifier()).getServerInfo();
                        return selected.contains(serverInfo);
                    }
                });
            }
        });

        hubFilter.setFocusable(false);
        setColumnWidth(hubFilter.getColumnModel().getColumn(0), 20);
        //прячем заголовок
        hubFilter.setTableHeader(null);
        hubFilterScrollPane.setColumnHeaderView(null);


        //слушатель обновляет таблицу результатов при поступлении новых данных
        listener = new HubEventListener() {
            public void onEvent(HubEvent e) {

                if (!isActive()) {
                    return;
                }
                if (e instanceof SearchResultRecieved) {
                    final SearchResultRecieved sr = (SearchResultRecieved) e;
                    SwingUtilities.invokeLater(new Runnable() {
                        public void run() {
                            SearchResultsTableModel model = (SearchResultsTableModel) resultsTable.getModel();
                            model.addResult(sr);
                            alert();
                            foundLabel.setText(Integer.toString(model.getRowCount()));
                        }
                    });
                }
            }
        };
        Application.getApplication().getHubEventsTranslator().addEventListener(listener);
        Application.getApplication().getExternalEventsTranslator().addEventListener(listener);

        SearchResultsTableModel model = new SearchResultsTableModel();
        resultsTable.setModel(model);
        resultsTable.setSortOrder(1, SortOrder.DESCENDING);
        resultsTable.setDefaultRenderer(ServerInfo.class, serverInfoRenderer);
        resultsTable.getColumnModel().getColumn(0).setCellRenderer(new SearchResultsRenderer());
        resultsTable.getColumnModel().getColumn(1).setCellRenderer(new SizeRenderer());
        resultsTable.getColumnModel().getColumn(0).setPreferredWidth(600);

        searchBtn.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent actionEvent) {
                doSearch();
            }
        });
        clearBtn.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                clear();
            }
        });

        setLayout(new BorderLayout());
        add(rootPanel, BorderLayout.CENTER);

        searchPattern.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0), "executeSearch");
        searchPattern.getActionMap().put("executeSearch", new AbstractAction() {
            public void actionPerformed(ActionEvent e) {
                doSearch();
            }
        });


        resultsTable.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {

                int row = resultsTable.rowAtPoint(e.getPoint());
                if (row<0) {
                    return;
                }
                int modelRow = resultsTable.convertRowIndexToModel(row);
                SearchResultsTableModel model = (SearchResultsTableModel) resultsTable.getModel();
                final SearchResultRecieved sr = model.getResult(modelRow);

                if (e.getClickCount()==2 && SwingUtilities.isLeftMouseButton(e)) {

                    DownloadItem item = new DownloadItem();
                    item.setFilename(sr.getFilename());
                    item.setLength(sr.getSize());
                    if (sr.getHubname().startsWith("TTH:")) {
                        item.setTth(sr.getHubname().substring(4));
                    }
                    item.getSource().setHub(sr.getServerInfo());
                    item.getSource().setNick(sr.getSourceNick());
                    Application.getApplication().getDownloadQueue().enqueueItem(item);
                }

                else if (e.getClickCount()==1 && SwingUtilities.isRightMouseButton(e)) {

                    JPopupMenu popup = new JPopupMenu();

                    if (sr.getHubname().startsWith("TTH:")) {
                        JMenuItem alt = new JMenuItem("Искать альтернативные");
                        alt.addActionListener(new ActionListener() {
                            public void actionPerformed(ActionEvent e) {
                                SearchRequest search = new SearchRequest();
                                search.setDataType(SearchConstants.SearchType.TTH);
                                search.setQuery(sr.getHubname().substring(4));
                                Application.getApplication().getMainFrame().search(search);
                            }
                        });
                        popup.add(alt);
                    }

                    popup.show(resultsTable, e.getX(), e.getY());

                }

            }
        });


        fileType.addItem(Search.SearchType.ANY);
        fileType.addItem(Search.SearchType.VIDEO);
        fileType.addItem(Search.SearchType.AUDIO);
        fileType.addItem(Search.SearchType.PICTURES);
        fileType.addItem(Search.SearchType.FOLDERS);
        fileType.addItem(Search.SearchType.EXECUTABLES);
        fileType.addItem(Search.SearchType.ARCHIVE);
        fileType.addItem(Search.SearchType.DOCUMENTS);
        fileType.addItem(Search.SearchType.TTH);
        fileType.setRenderer(new LocalizedListCellRenderer());

        sizeType.addItem(SearchConstants.SearchSizeType.IGNORE);
        sizeType.addItem(SearchConstants.SearchSizeType.NOT_LESS);
        sizeType.addItem(SearchConstants.SearchSizeType.LESS);
        sizeType.setRenderer(new LocalizedListCellRenderer());

        searchMult.addItem(SearchConstants.SearchSizeMultiplier.BYTES);
        searchMult.addItem(SearchConstants.SearchSizeMultiplier.KB);
        searchMult.addItem(SearchConstants.SearchSizeMultiplier.MB);
        searchMult.addItem(SearchConstants.SearchSizeMultiplier.GB);
    }

    private void setColumnWidth(TableColumn column, int w) {
        column.setWidth(w);
        column.setMaxWidth(w);
        column.setMinWidth(w);
        column.setPreferredWidth(w);
    }


    @Override
    public void onSelect() {
        super.onSelect();
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                searchPattern.requestFocusInWindow();
            }
        });
    }

    public void doSearch() {


        SearchConstants.SearchSizeType sizeT  = (SearchConstants.SearchSizeType) sizeType.getSelectedItem();


        SearchRequest search = new SearchRequest();
        search.setDataType((SearchConstants.SearchType) fileType.getSelectedItem());
        search.setSizeRestricted(sizeT.isMaxSize()!=null);
        search.setMaxSize(sizeT.isMaxSize()!=null && sizeT.isMaxSize());
        search.setSize(sizeT.isMaxSize()!=null ? getSearchtSize() : 0);
        search.setQuery(searchPattern.getText());

        search(search);

    }

    public void search(SearchRequest request) {

        Application.getApplication().getMainFrame().markSearchTabActive(this);

        resetResults();

        if (!fileType.getSelectedItem().equals(request.getDataType())) {
            fileType.setSelectedItem(request.getDataType());
        }

        logger.info("Searching: "+request.getQuery());
        setTitle("Поиск: "+request.getQuery());

        ConnectionManager manager = Application.getApplication().getConnectionManager();
        for (ServerInfo hub : manager.enumerateHubConnections()) {
            manager.search(hub, request);
        }
    }

    private void resetResults() {
        SearchResultsTableModel model = (SearchResultsTableModel) resultsTable.getModel();
        model.clear();
        foundLabel.setText("0");
    }

    private void clear() {
        resetResults();
        fileType.setSelectedIndex(0);
        sizeType.setSelectedIndex(0);
        searchMult.setSelectedIndex(0);
        size.setText("");
        searchPattern.setText("");
    }

    private Long getSearchtSize() {
        Long sizeRestriction;
        try {
            sizeRestriction = new Long(size.getText());
        } catch (NumberFormatException e) {
            sizeRestriction = 0L;
        }
        SearchConstants.SearchSizeMultiplier mult = (SearchConstants.SearchSizeMultiplier) searchMult.getSelectedItem();
        sizeRestriction*=mult.getMultiplier();
        return sizeRestriction;
    }

    public JTextField getSearchPattern() {
        return searchPattern;
    }


    public void close() {
        Application.getApplication().getHubEventsTranslator().removeEventListener(listener);
        Application.getApplication().getExternalEventsTranslator().removeEventListener(listener);
    }

    public boolean isActive() {
        return active;
    }

    public void setActive(boolean active) {
        this.active = active;
    }
}



